#ifndef UnstructMG_GCR_HPP
#define UnstructMG_GCR_HPP

#include "iter_solver.hpp"

template<typename idx_t, typename pc_data_t, typename pc_calc_t, typename ksp_t, int dof>
class GCRSolver : public IterativeSolver<idx_t, pc_data_t, pc_calc_t, ksp_t, dof> {
public:
    GCRSolver();
    void SetInnerIterMax(int num);
protected:
    // iter_max+1就是重启长度，闭区间[0, iter_max]
    int inner_iter_max = 10;
    // 求解以b为右端向量的方程组，x为返回的近似解
    void Mult_ipl(const par_Vector<idx_t, ksp_t, dof> & b, par_Vector<idx_t, ksp_t, dof> & x) const ;
};

typedef GCRSolver<int, double, double, double, 1> GCRSolver_I32All64_DOF1;
typedef GCRSolver<int, double, double, double, 2> GCRSolver_I32All64_DOF2;
typedef GCRSolver<int, double, double, double, 3> GCRSolver_I32All64_DOF3;
typedef GCRSolver<int, double, double, double, 4> GCRSolver_I32All64_DOF4;

typedef GCRSolver<int, float , double, double, 1> GCRSolver_I32K64P64D32_DOF1;
typedef GCRSolver<int, float , double, double, 2> GCRSolver_I32K64P64D32_DOF2;
typedef GCRSolver<int, float , double, double, 3> GCRSolver_I32K64P64D32_DOF3;
typedef GCRSolver<int, float , double, double, 4> GCRSolver_I32K64P64D32_DOF4;

typedef GCRSolver<int, float , float , double, 1> GCRSolver_I32K64P32D32_DOF1;
typedef GCRSolver<int, float , float , double, 2> GCRSolver_I32K64P32D32_DOF2;
typedef GCRSolver<int, float , float , double, 3> GCRSolver_I32K64P32D32_DOF3;
typedef GCRSolver<int, float , float , double, 4> GCRSolver_I32K64P32D32_DOF4;

typedef GCRSolver<int, float , float , float , 1> GCRSolver_I32All32_DOF1;
typedef GCRSolver<int, float , float , float , 2> GCRSolver_I32All32_DOF2;
typedef GCRSolver<int, float , float , float , 3> GCRSolver_I32All32_DOF3;
typedef GCRSolver<int, float , float , float , 4> GCRSolver_I32All32_DOF4;
#ifdef USE_FP16
typedef GCRSolver<int, __fp16, float , double, 1> GCRSolver_I32K64P32D16_DOF1;
typedef GCRSolver<int, __fp16, float , double, 2> GCRSolver_I32K64P32D16_DOF2;
typedef GCRSolver<int, __fp16, float , double, 3> GCRSolver_I32K64P32D16_DOF3;
typedef GCRSolver<int, __fp16, float , double, 4> GCRSolver_I32K64P32D16_DOF4;

typedef GCRSolver<int, __fp16, float , float , 1> GCRSolver_I32K32P32D16_DOF1;
typedef GCRSolver<int, __fp16, float , float , 2> GCRSolver_I32K32P32D16_DOF2;
typedef GCRSolver<int, __fp16, float , float , 3> GCRSolver_I32K32P32D16_DOF3;
typedef GCRSolver<int, __fp16, float , float , 4> GCRSolver_I32K32P32D16_DOF4;
#endif
#endif